using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//定义每个订阅的名称
public enum EventType
{
    textshowme,
}

//可序列化字典
[Serializable]
public class EventDictionary : SerializedDictionary<EventType,Delegate > { }

public class 事件管理器 : 事件管理单例<事件管理器>
{
    private static EventDictionary  EventTable = new EventDictionary();

    /// <summary>
    /// 添加事件
    /// </summary>
    /// <param 事件名称类型="eventType"></param>
    /// <param 回调函数="callback"></param>
    
    //在需要被执行函数的地方使用，发布任务
    private static void CheckAddListener(EventType eventType, Delegate callback)
    {
        if (!EventTable.ContainsKey(eventType))
        {
            EventTable.Add(eventType, null);
        }
        Delegate del = EventTable[eventType];
        if (del != null && callback.GetType() != del.GetType())
        {
            throw new Exception(string.Format("添加了不同类型Callback"));
        }
    }
    public static void AddListener(EventType eventType,CallBack callBack)
    {
        CheckAddListener(eventType, callBack);
        EventTable[eventType] = (CallBack)EventTable[eventType]+ callBack;
    }
    public static void AddListener<T>(EventType eventType, CallBack<T> callBack)
    {
        CheckAddListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T>)EventTable[eventType] + callBack;
    }
    public static void AddListener<T,X>(EventType eventType, CallBack<T,X> callBack)
    {
        CheckAddListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T,X>)EventTable[eventType] + callBack;
    }
    public static void AddListener<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack)
    {
        CheckAddListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T, X, Y>)EventTable[eventType] + callBack;
    }
    public static void AddListener<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack)
    {
        CheckAddListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T, X, Y, Z>)EventTable[eventType] + callBack;
    }
    //移除事件//////////
    //删除物体时取消任务
    private static void CheckRemoveListener(EventType eventType,Delegate callBack)
    {
        if (EventTable.ContainsKey(eventType))
        {
            Delegate del = EventTable[eventType];
            if (del == null)
            {
                throw new Exception(string.Format("当前委托列表无监听"));
            }
            else if (del.GetType() != del.GetType())
            {
                throw new Exception(string.Format("试图移除不同类型Callback"));
            }
        }
        else
            throw new Exception(string.Format("无当前委托列表"));
    }
    public static void RemoveListener(EventType eventType, CallBack callBack)
    {
        CheckRemoveListener(eventType, callBack);
        EventTable[eventType] = (CallBack)EventTable[eventType] - callBack;
        if (EventTable[eventType] == null) EventTable.Remove(eventType);
    }
    public static void RemoveListener<T>(EventType eventType, CallBack<T> callBack)
    {
        CheckRemoveListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T>)EventTable[eventType] - callBack;
        if (EventTable[eventType]==null) EventTable.Remove(eventType);
    }
    public static void RemoveListener<T, X>(EventType eventType, CallBack<T, X> callBack)
    {
        CheckRemoveListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T, X>)EventTable[eventType] - callBack;
        if (EventTable[eventType] == null) EventTable.Remove(eventType);
    }
    public static void RemoveListener<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack)
    {
        CheckRemoveListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T, X, Y>)EventTable[eventType] - callBack;
        if (EventTable[eventType] == null) EventTable.Remove(eventType);
    }
    public static void RemoveListener<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack)
    {
        CheckRemoveListener(eventType, callBack);
        EventTable[eventType] = (CallBack<T, X, Y, Z>)EventTable[eventType] - callBack;
        if (EventTable[eventType] == null) EventTable.Remove(eventType);
    }
    //广播事件//////////
    //在需要触发函数的地方使用，接取并完成所有同类型任务
    public static void Broadcast(EventType eventType)
    {
        Delegate del;
        if(EventTable.TryGetValue(eventType, out del))
        {
            CallBack callBack=del as CallBack;
            if(callBack != null)callBack();  
            else throw new Exception(string.Format("试图广播不同类型Callback")); 
        }
    }
    public static void Broadcast<T>(EventType eventType,T val1)
    {
        Delegate del;
        if (EventTable.TryGetValue(eventType, out del))
        {
            CallBack<T> callBack = del as CallBack<T>;
            if (callBack != null)callBack(val1);
            throw new Exception(string.Format("试图广播不同类型Callback"));
        }
    }
    public static void Broadcast<T, X>(EventType eventType, T val1,X val2)
    {
        Delegate del;
        if (EventTable.TryGetValue(eventType, out del))
        {
            CallBack<T, X> callBack = del as CallBack<T, X>;
            if (callBack != null) callBack(val1, val2);
            throw new Exception(string.Format("试图广播不同类型Callback"));
        }
    }
    public static void Broadcast<T, X, Y>(EventType eventType, T val1, X val2,Y val3)
    {
        Delegate del;
        if (EventTable.TryGetValue(eventType, out del))
        {
            CallBack<T, X, Y> callBack = del as CallBack<T, X, Y>;
            if (callBack != null) callBack(val1, val2, val3);
            throw new Exception(string.Format("试图广播不同类型Callback"));
        }
    }
    public static void Broadcast<T, X, Y, Z>(EventType eventType, T val1, X val2, Y val3,Z val4)
    {
        Delegate del;
        if (EventTable.TryGetValue(eventType, out del))
        {
            CallBack<T, X, Y, Z> callBack = del as CallBack<T, X, Y, Z>;
            if (callBack != null) callBack(val1, val2, val3, val4);
            throw new Exception(string.Format("试图广播不同类型Callback"));
        }
    }
}